package site.lanmushan.generate.service;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import site.lanmushan.generate.configs.GenerateCodeConfig;
import site.lanmushan.generate.configs.TemplateConfig;
import site.lanmushan.generate.entity.Column;
import site.lanmushan.generate.entity.Table;
import site.lanmushan.generate.mapper.GenerateTableMapper;
import site.lanmushan.generate.util.StringUtil;
import site.lanmushan.generate.util.VelocityUtil;

import java.io.*;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author Administrator
 */
@Service
@Slf4j
public class GenerateCodeService {
    @Autowired
    private GenerateTableMapper generateTableMapper;
    GenerateCodeConfig config;

    /**
     * @param config
     */
    public void generate(GenerateCodeConfig tconf) {
        config = tconf;
        if (config.getTableList() == null) {
            return;
        }
        List<Table> tableList = createTable(config);
        tableList.forEach(it -> {
            log.info("生成数据表:{} 相关参数:{}", it.getTableName(), JSONObject.toJSONString(it));
            printTableFile(config.getDirectoryPath(), it, config.getTemplateList());
        });
    }

    private void printTableFile(String path, Table table, List<TemplateConfig> templateList) {
        templateList.forEach(it -> {
            try {
                log.info("输出到文件:{} 模板名称:{}", path, it.getTplName());
                Template template = null;
                if (StringUtils.isEmpty(config.getTplDirectoryPath())) {
                    template = VelocityUtil.getVelocityTemplateByClassPath("tpl\\" + it.getTplName());
                } else {
                    template = VelocityUtil.getVelocityTemplateByPath(config.getTplDirectoryPath(), it.getTplName());
                }
                FileWriter pw = new FileWriter(createFile(createFileName(it, table, path)));
                StringWriter sw = new StringWriter();
                VelocityContext ctx = new VelocityContext((Map) JSONObject.toJSON(table));
                ctx.put("su", StringUtil.class);
                template.merge(ctx, sw);
                template.merge(ctx, pw);
                pw.flush();
                pw.close();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }

        });
    }

    /**
     * 创建文件名称
     *
     * @param templateConfig
     * @param table
     * @param rootPath
     * @return
     */
    public String createFileName(TemplateConfig templateConfig, Table table, String rootPath) {
        if (StringUtils.isEmpty(templateConfig.getPrefix())) {
            templateConfig.setPrefix("");
        }
        if (StringUtils.isEmpty(templateConfig.getSuffix())) {
            templateConfig.setSuffix("");
        }
        String fileName = null;
        String tplName = templateConfig.getTplName();

        if (StringUtils.isEmpty(templateConfig.getOutName())) {
            fileName = templateConfig.getPrefix() + table.getEntityName() + templateConfig.getSuffix()+tplName.substring(tplName.lastIndexOf("."), tplName.length());;
        } else {
            fileName = templateConfig.getPrefix() + templateConfig.getOutName() + templateConfig.getSuffix();
        }
        if (templateConfig.isLowFirst()) {
            fileName = StringUtil.toLowerCaseFirstOne(fileName);
        }
        String resultPath = "";
        if (StringUtils.isEmpty(templateConfig.getDir())) {
            resultPath = rootPath + File.separator + table.getTableName() + File.separator + fileName;


        } else {
            resultPath = rootPath + File.separator + table.getTableName() + File.separator + templateConfig.getDir() + File.separator + fileName;
            return resultPath;

        }
        log.info("输出路径:{}", resultPath);
        return resultPath;
    }

    public File createFile(String fileName) {
        File file = new File(fileName);
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        return file;
    }

    private List<Table> createTable(GenerateCodeConfig config) {
        List<Table> tableList = generateTableMapper.selectAllTable(config.getDatabase());
        tableList = tableList.stream().filter(it -> {
            it.setAppCode(config.getAppCode());
            return config.getTableList().contains(it.getTableName());
        }).collect(Collectors.toList());

        tableList.stream().forEach(it -> {
            it.setPackageName(config.getPackageName());
            List<Column> columnList = generateTableMapper.selectColumnByTable(it.getTableName(), config.getDatabase());
            columnList = columnList.stream().map(column -> {
                column.init();
                return column;
            }).collect(Collectors.toList());
            it.setFullColumnList(columnList);
            columnList = columnList.stream().filter(column -> {
                return !config.getIgnoreColumn().contains(column.getColumn_name());
            }).collect(Collectors.toList());
            it.setColumnList(columnList);
        });
        return tableList;
    }
}
